import pymysql
import uuid

import random
import string

import cx_Oracle
import psycopg2
from random_words import LoremIpsum
from random_words import RandomWords
from tqdm import tqdm

'''编写时间：2024/11/12'''
'''编写人：董乐乐'''
'''支持DB：Mysql'''


# 连接数据库
def word_vl(letter):
    rw = RandomWords()
    word = rw.random_words(letter=letter, count=1)
    table_name2 = ','.join(str(i) for i in word)
    return table_name2


def create_table(dbtype, host, user, port, password, db, schema,file, rows, table_prefix):
    global inser_data, cur, conn
    pre_tbname = word_vl(letter=table_prefix)
    #pre_tbname = table_prefix + ''.join(random.choices(string.ascii_lowercase, k=6))

    if dbtype == 'MySQL':
        inser_data = db + '.' + pre_tbname
        print('【INFO——>大表环境创建】：已选择【MySQL】数据库类型创建大表环境')
        conn = pymysql.connect(host=host, user=user, port=port, password=password, db=db)
        # 创建游标
        cur = conn.cursor()
        cur.execute(
    f"""
    CREATE TABLE {inser_data} (
        id varchar(255),
        order_no varchar(155),
        order_deal varchar(255),
        order_add varchar(55),
        order_sku varchar(235),
        name varchar(251),
        gender varchar(95),
        phone varchar(100),
        zipcode varchar(112),
        repo_addr varchar(122),
        city varchar(122),
        city2 varchar(122),
        city3 varchar(122),
        city4 varchar(122),
        city5 varchar(122),
        city6 varchar(122),
        city7 varchar(122),
        city8 varchar(122),
        city9 varchar(122),
        city10 varchar(122),
        PRIMARY KEY (id, order_no)
    );
    """
)

    elif dbtype == 'Oracle':
        inser_data = schema + '.' + pre_tbname
        print('【INFO——>大表环境创建】：已选择【Oracle】数据库类型创建大表环境')
        conn = cx_Oracle.connect(
            user=user,
            password=password,
            dsn=f"{host}:{port}/{db}"
        )
        # 创建游标
        cur = conn.cursor()
        try:
            cur.execute(f"""
            CREATE TABLE {inser_data} (
                id VARCHAR2(255),
                order_no VARCHAR2(155),
                order_deal VARCHAR2(255),
                order_add VARCHAR2(55),
                order_sku VARCHAR2(235),
                name VARCHAR2(251),
                gender VARCHAR2(95),
                phone VARCHAR2(100),
                zipcode VARCHAR2(112),
                repo_addr VARCHAR2(122),
                city VARCHAR2(122),
                city2 VARCHAR2(122),
                city3 VARCHAR2(122),
                city4 VARCHAR2(122),
                city5 VARCHAR2(122),
                city6 VARCHAR2(122),
                city7 VARCHAR2(122),
                city8 VARCHAR2(122),
                city9 VARCHAR2(122),
                city10 VARCHAR2(122),
                CONSTRAINT pk_{pre_tbname} PRIMARY KEY (id, order_no)
            )
            """)
            conn.commit()
            print("表创建成功")
            print('【INFO——>大表环境创建】-tablename is:' + inser_data)
        except cx_Oracle.DatabaseError as e:
            print(f"创建表失败: {e}")
        finally:
            cur.close()
            conn.close()
    elif dbtype == 'PostgreSQL':
        print('【INFO——>大表环境创建】：已选择【Postgres】数据库类型创建大表环境')
        conn = psycopg2.connect(host=host, port=port, user=user, password=password, dbname=db)
        # 创建游标
        cur = conn.cursor()
        inser_data = 'public' + '.' + pre_tbname
        cur.execute(
            f"""
            CREATE TABLE {inser_data} (
                id varchar(255),
                order_no varchar(155),
                order_deal varchar(255),
                order_add varchar(55),
                order_sku varchar(235),
                name varchar(251),
                gender varchar(95),
                phone varchar(100),
                zipcode varchar(112),
                repo_addr varchar(122),
                city varchar(122),
                city2 varchar(122),
                city3 varchar(122),
                city4 varchar(122),
                city5 varchar(122),
                city6 varchar(122),
                city7 varchar(122),
                city8 varchar(122),
                city9 varchar(122),
                city10 varchar(122),
                PRIMARY KEY (id, order_no)
            );
            """
        )
        conn.commit()
        print("表创建成功")
        print('【INFO——>大表环境创建】-tablename is:' + inser_data)
    elif dbtype == 'DM':
        inser_data = db + '.' + pre_tbname
        print('【INFO——>大表环境创建】：已选择【达梦】数据库类型创建大表环境')
        import jaydebeapi
        # 设置数据库连接信息
        jdbc_url = f"jdbc:dm://{host}:{port}"  # 5236为实例端口号，每个实例对应的端口号不同，这里通过指定端口号来连接到不同实例中，不需要实例名
        jdbc_driver = "dm.jdbc.driver.DmDriver"
        jdbc_jar_path = r"./jdbc_driver/DmJdbcDriver18.jar"  # 替换成实际的 JDBC 驱动 JAR 文件路径
        conn = jaydebeapi.connect(jdbc_driver, jdbc_url, [user, password], jdbc_jar_path)
        # 创建游标
        cur = conn.cursor()
        cur.execute(
            f"""
            CREATE TABLE {inser_data} (
                id varchar(255),
                order_no varchar(155),
                order_deal varchar(255),
                order_add varchar(55),
                order_sku varchar(235),
                name varchar(251),
                gender varchar(95),
                phone varchar(100),
                zipcode varchar(112),
                repo_addr varchar(122),
                city varchar(122),
                city2 varchar(122),
                city3 varchar(122),
                city4 varchar(122),
                city5 varchar(122),
                city6 varchar(122),
                city7 varchar(122),
                city8 varchar(122),
                city9 varchar(122),
                city10 varchar(122),
                PRIMARY KEY (id, order_no)
            );
            """
        )
        print('【INFO——>大表环境创建】-tablename is:' + inser_data)

    # 随机生成字符串
    def random_string(length, chars=string.ascii_letters + string.digits + string.punctuation):
        return ''.join(random.choices(chars, k=length))

    # 随机生成地址字符串
    def generate_address():
        street = ['NanJing', 'HuaiHai', 'HanDan', 'GuoDing', 'GuoQuan', 'JinLing', 'ZhongShan', 'LongMing', 'QinZhou',
                  'JiPu',
                  'BaoShan', 'JiangPu', 'ShanTou', 'HeNan', 'JiangXi', 'YunNan', 'BeiJing', 'ChengDu', 'ChongQing',
                  'HanZhong']
        street_value = random.choice(street)
        return f"Room {random.randint(1, 9999)} No.{random.randint(1, 9999)} {random_string(5)} {random_string(5)} {street_value} Road China"

    # 批量生成数据，一次性生成数据
    generated_col0 = set()

    def generate_unique_col0(allow_duplicates=False):
        while True:
            # Generate a random UUID for col0
            col0 = str(uuid.uuid4())

            # Ensure the col0 is always unique by checking the set
            if col0 not in generated_col0:
                generated_col0.add(col0)  # Add the generated UUID to the set
                return col0

            # If duplicates are allowed, then we may randomly pick an existing UUID from the set
            if allow_duplicates:
                # 80% chance to pick a duplicate
                if generated_col0 and random.random() < 0.8:
                    col0 = random.choice(list(generated_col0))  # Randomly pick an existing UUID
                    return col0
                else:
                    # 20% chance to generate a new unique UUID
                    continue  # Continue the loop to generate a new unique UUID

    def generate_data(rows):
        li = LoremIpsum()
        data = []
        print(f'INFO->【大表环境创建】:开始生成要插入的测试数据，下方展示生成进度', )
        # 使用 tqdm 显示进度条
        for _ in tqdm(range(rows), desc="Generating data", ncols=100, unit="row", file=file):
            # col0 = random.randint(1,9999999999999),li.get_sentences(1)
            # col0 = random.randint(1,9999999999999)
            col0 = str(uuid.uuid4())
            col1 = generate_address()
            col2 = generate_address()
            col3 = generate_address()
            col4 = generate_address()
            col5 = generate_address()
            col6 = generate_address()
            col7 = generate_address()
            col8 = generate_address()
            col9 = generate_address()
            col10 = generate_address()
            col11 = generate_address()
            col12 = generate_address()
            col13 = generate_address()
            col14 = generate_address()
            col15 = generate_address()
            col16 = generate_address()
            col17 = generate_address()
            col18 = generate_address()
            col19 = generate_address()
            

            # 将生成的数据添加到列表中
            data.append((col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11,col12,col13,col14,col15,col16,col17,col18,col19))
            # data.append((col0, col1, col2, col3, col4, col5, col6, col7, col8, col9, col10, col11))
        print(f'INFO->【大表环境创建】:测试数据生成完成，下一步进行插入数据库', )
        return data
    if dbtype == 'DM':
        import jaydebeapi
        jdbc_url = f"jdbc:dm://{host}:{port}"  # 5236为实例端口号，每个实例对应的端口号不同，这里通过指定端口号来连接到不同实例中，不需要实例名
        jdbc_driver = "dm.jdbc.driver.DmDriver"
        jdbc_jar_path = r"./jdbc_driver/DmJdbcDriver18.jar"  # 替换成实际的 JDBC 驱动 JAR 文件路径
        conn = jaydebeapi.connect(jdbc_driver, jdbc_url, [user, password], jdbc_jar_path)
        # 创建游标
        cur = conn.cursor()
        for i in range(4):
        # 生成100万行数据，一次性生成100万数据，只插入一次数据库
            rows = rows  # 更改一次性生成的数据大小
            data = generate_data(rows)

            for i in range(1):  # 生成100万行数据，一次性生成100万数据，只插入一次数据库
                print(f'INFO->【大表环境创建】:测试数据已生成，开始插入数据库,请等待完成.......', )
                if dbtype == 'DM':
                    sql2 = f'insert into {inser_data} VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)'
                    cur.executemany(sql2, data)
                    conn.commit()
                print(f'INFO->【大表环境创建】:正在对大表进行插入，已完成一次{rows}行的数据构建', )
        cur.close()
        conn.close()

    elif dbtype == 'MySQL':
        conn = pymysql.connect(host=host, user=user, port=port, password=password, db=db)
        # 创建游标
        cur = conn.cursor()
        for i in range(100):
        # 生成100万行数据，一次性生成100万数据，只插入一次数据库
            rows = rows  # 更改一次性生成的数据大小
            data = generate_data(rows)

            for i in range(1):  # 生成100万行数据，一次性生成100万数据，只插入一次数据库
                print(f'INFO->【大表环境创建】:测试数据已生成，开始插入数据库,请等待完成.......', )
                if dbtype == 'MySQL':
                    sql2 = f'insert into {inser_data} VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
                    cur.executemany(sql2, data)
                    conn.commit()
                print(f'INFO->【大表环境创建】:正在对大表进行插入，已完成一次{rows}行的数据构建', )
        cur.close()
        conn.close()
    elif dbtype == 'Oracle':
        conn = cx_Oracle.connect(
            user=user,
            password=password,
            dsn=f"{host}:{port}/{db}"
        )
        # 创建游标
        cur = conn.cursor()
        for i in range(1):
        # 生成100万行数据，一次性生成100万数据，只插入一次数据库
            rows = rows  # 更改一次性生成的数据大小
            data = generate_data(rows)

            for i in range(1):  # 生成100万行数据，一次性生成100万数据，只插入一次数据库
                print(f'INFO->【大表环境创建】:测试数据已生成，开始插入数据库,请等待完成.......', )
                if dbtype == 'Oracle':
                    sql2 = f'insert into {inser_data} VALUES(:1, :2, :3, :4, :5, :6, :7, :8, :9, :10, :11,:12,:13,:14,:15,:16,:17,:18,:19,:20)'
                    cur.executemany(sql2, data)
                    conn.commit()
                print(f'INFO->【大表环境创建】:正在对大表进行插入，已完成一次{rows}行的数据构建', )
        cur.close()
        conn.close()
    elif dbtype == 'PostgreSQL':
        conn = psycopg2.connect(host=host, port=port, user=user, password=password, dbname=db)
        # 创建游标
        cur = conn.cursor()
        for i in range(100):
            # 生成100万行数据，一次性生成100万数据，只插入一次数据库
            rows = rows  # 更改一次性生成的数据大小
            data = generate_data(rows)

            for i in range(1):  # 生成100万行数据，一次性生成100万数据，只插入一次数据库
                print(f'INFO->【大表环境创建】:测试数据已生成，开始插入数据库,请等待完成.......', )
                if dbtype == 'PostgreSQL':
                    sql2 = f'insert into {inser_data} VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)'
                    cur.executemany(sql2, data)
                    conn.commit()
                print(f'INFO->【大表环境创建】:正在对大表进行插入，已完成一次{rows}行的数据构建', )
        cur.close()
        conn.close()

